#include "CodeExercise.h"

Exercise::Exercise(std::string input_filename, std::string output_filename, vector<string> query, string format){
    this->input_filename = PREFIX + input_filename;
    this->output_filename = PREFIX + output_filename;
    this->input_stream = std::ifstream(this->input_filename);
    this->output_stream = std::ofstream(this->output_filename);
    this->query = query;
    this->str_format = format;
}
int Exercise::next_line(std::string & str) {
    if (!getline(this->input_stream, str))
        return -1;
    return 0;
}
vector<string> Exercise::separate_string(const std::string &s, char separator) {
    vector<string> result;
    unsigned int posBegin = 0;
    unsigned int posEnd = 0;
    while(posEnd != s.length()){
        if (s[posEnd] == separator){
            result.push_back(s.substr(posBegin, posEnd - posBegin));
            posBegin = posEnd + 1;
        }
        posEnd++;
    }
    if (posEnd != posBegin)
        result.push_back(s.substr(posBegin, posEnd));
    return result;
}
void Exercise::run(){
    string str;
    while (this->next_line(str) != -1) {
        vector<string> vec = this->separate_string(str, this->separator);
        //if not find operations in map, build it
        if (op_map.find(vec[1]) == op_map.end()) {
            op_map[vec[1]] = vector<Operation>();
            vector<Operation> &vec_tmp = op_map[vec[1]];
            build_operations(vec_tmp);
        }
        int64_t time_stamp = stoll(vec[0]);
        string symbol = vec[1];
        int64_t quality = stoll(vec[2]);
        int64_t price = stoll(vec[3]);
        base_data["TimeStamp"] = time_stamp;
        base_data["Quantity"] = quality;
        base_data["Price"] = price;

        vector<Operation> & vec_tmp = op_map[symbol];
        for (auto & i : vec_tmp)
            i.update();
    }
}
void Exercise::build_operations(vector<Operation> & vec){
    for (auto & i : query) {
        Operation op(i, base_data);
        op.type = "root";
        vec.push_back(op);
    }
}

void Exercise::write_to_file() {
    //analyze the given format
    int posBegin = 0, posEnd = 0;
    while(posEnd != str_format.size()) {
        if (str_format[posEnd] == ',') {
            vec_format.push_back(str_format.substr(posBegin, posEnd - posBegin));
            posBegin = posEnd +1;
        }
        posEnd ++;
    }
    if (posEnd != posBegin)
        vec_format.push_back(str_format.substr(posBegin, posEnd - posBegin));
    for (int i=0; i<vec_format.size(); i++){
        if (vec_format[i] == "Symbol") query_mark.push_back(-1);
        else
            for (int j=0; j<query.size(); j++){
                string str1 = vec_format[i], str2 = query[j];
                if (str2.substr(0, str1.size()) == str1){
                    query_mark.push_back(j);
                    break;
                }
            }
    }

    for (auto & s : this->op_map){
        vector<Operation> & ops = s.second;
        int len = ops.size();
        if (len == 0) return ;
        if (query_mark[0] == -1)
            output_stream<<s.first;
        else output_stream<<ops[query_mark[0]].getResult();
        for (int i=1; i<=len; i++){
            if (query_mark[i] == -1)
                output_stream<<','<<s.first;
            else output_stream<<','<<ops[query_mark[i]].getResult();
        }
        output_stream<<'\n';
    }
}
